home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / dviware / vutex / vaxvms.chg < prev    next >
Text File  |  1990-10-01  |  19KB  |  633 lines

  1.  VMS changes file for the ASCII driver written by Warren Wolfe, Aug, 1988
  2.  Copyright 1987 CUBE Software, Victoria, B.C., Canada
  3.  
  4. @x [2]
  5. @d banner=='This is ',clone,', Version 1.00'
  6. @y
  7. @d banner=='This is ',clone,', VAX/VMS Version 1.00'
  8. @z
  9.  
  10. @x
  11. @d othercases == others: {default for cases not listed explicitly}
  12. @d endcases == @+end {follows the default case in an extended |case| statement}
  13. @f othercases == else
  14. @f endcases == end
  15. @y
  16. @d othercases == otherwise {default for cases not listed explicitly}
  17. @d endcases == @+end {follows the default case in an extended |case| statement}
  18. @f othercases == else
  19. @f endcases == end
  20. @z
  21.  
  22. @x [4] add tfm_file,gen_input,and input to program header
  23. @p program vutex(dvi_file,bit_file,input,output);
  24. @y
  25. @p
  26. @\@=[inherit('sys$library:starlet')]@>@\
  27.  {allows us to use system symbols and routines}
  28. program vutex(dvi_file,bit_file,tfm_file,gen_input,input,output);
  29. @z
  30.  
  31. @x
  32. procedure initialize; {this procedure gets things started properly}
  33.   var i:integer; {loop index for initializations}
  34.   begin print_ln(banner);@/
  35. @y
  36. @<Procedures for initialization@>@/
  37. procedure initialize; {this procedure gets things started properly}
  38.   var i:integer; {loop index for initializations}
  39.   begin
  40.   @<Preset initial values@>@/
  41.   print_ln(banner);@/
  42. @z
  43.  
  44. @x
  45. Some \PASCAL\ compilers use the original name |char| for the data type
  46. associated with the characters in text files, while other \PASCAL s
  47. consider |char| to be a 64-element subrange of a larger data type that has
  48. some other name.  In order to accommodate this difference, we shall use
  49. the name |text_char| to stand for the data type of the characters in the
  50. output file.  We shall also assume that |text_char| consists of
  51. the elements |chr(first_text_char)| through |chr(last_text_char)|,
  52. inclusive. The following definitions should be adjusted if necessary.
  53. @^system dependencies@>
  54.  
  55. @d text_char == char {the data type of characters in text files}
  56. @d first_text_char=0 {ordinal number of the smallest element of |text_char|}
  57. @d last_text_char=127 {ordinal number of the largest element of |text_char|}
  58.  
  59. @<Types...@>=
  60. @!text_file=packed file of text_char;
  61. @y
  62. Some \PASCAL\ compilers use the original name |char| for the data type
  63. associated with the characters in text files, while other \PASCAL s
  64. consider |char| to be a 64-element subrange of a larger data type that has
  65. some other name.  In order to accommodate this difference, we shall use
  66. the name |text_char| to stand for the data type of the characters in the
  67. output file.  We shall also assume that |text_char| consists of
  68. the elements |chr(first_text_char)| through |chr(last_text_char)|,
  69. inclusive. The following definitions should be adjusted if necessary.
  70. @^system dependencies@>
  71.  
  72. @d text_char == char {the data type of characters in text files}
  73. @d first_text_char=0 {ordinal number of the smallest element of |text_char|}
  74. @d last_text_char=127 {ordinal number of the largest element of |text_char|}
  75.  
  76. @<Types...@>=
  77. @!text_file=text;
  78. @z
  79.  
  80. @x
  81. @!byte_file=packed file of eight_bits; {files that contain binary data}
  82. @y
  83. {later we'll define files that contain binary data}
  84. @z
  85.  
  86. @x
  87. @!dvi_file:byte_file; {the stuff we are \.{DVI}typing}
  88. @!tfm_file:byte_file; {a font metric file}
  89. @y
  90. @!dvi_file:packed file of byte_block; {the stuff we are \.{DVI}typing}
  91. @!tfm_file:packed file of byte_block; {a font metric file}
  92. @!dvi_count:integer; {number of bytes read from current block of |dvi_file|}
  93. @!tfm_count:integer; {number of bytes read from current block of |tfm_file|}
  94. @!dvi_blocks:integer; {number of blocks in |dvi_file|}
  95. @z
  96.  
  97. @x Initialize byte counter for block in open_dvi_file
  98. begin reset(dvi_file);
  99. @y
  100. begin reset(dvi_file);
  101. dvi_count:=0;
  102. @z
  103.  
  104. @x And again in reopen_dvi_file
  105. begin reset(dvi_file);
  106. @y
  107. begin reset(dvi_file);
  108. dvi_count:=0;
  109. @z
  110.  
  111. @x
  112. begin reset(tfm_file,cur_name);
  113. @y
  114. begin close(tfm_file,@=error@>:=@=continue@>); {stupid Vax/VMS run-times}
  115. open(tfm_file,cur_name,@=old@>,@=error@>:=@=continue@>);
  116. reset(tfm_file,@=error@>:=@=continue@>);
  117. tfm_count:=0;
  118. @z
  119.  
  120. @x
  121. begin reset(gen_input, cur_name) ;
  122. @y
  123. begin close(gen_input,@=error@>:=@=continue@>);
  124. open(gen_input,cur_name,@=old@>,@=error@>:=@=message@>);
  125. reset(gen_input,@=error@>:=@=message@>);
  126. @z
  127.  
  128. @x
  129. @p function get_byte:integer; {returns the next byte, unsigned}
  130. var b:eight_bits;
  131. begin if eof(dvi_file) then get_byte:=0
  132. else  begin read(dvi_file,b); incr(cur_loc); get_byte:=b;
  133.   end;
  134. end;
  135. @#
  136. function signed_byte:integer; {returns the next byte, signed}
  137. var b:eight_bits;
  138. begin read(dvi_file,b); incr(cur_loc);
  139. if b<128 then signed_byte:=b @+ else signed_byte:=b-256;
  140. end;
  141. @#
  142. function get_two_bytes:integer; {returns the next two bytes, unsigned}
  143. var a,@!b:eight_bits;
  144. begin read(dvi_file,a); read(dvi_file,b);
  145. cur_loc:=cur_loc+2;
  146. get_two_bytes:=a*256+b;
  147. end;
  148. @#
  149. function signed_pair:integer; {returns the next two bytes, signed}
  150. var a,@!b:eight_bits;
  151. begin read(dvi_file,a); read(dvi_file,b);
  152. cur_loc:=cur_loc+2;
  153. if a<128 then signed_pair:=a*256+b
  154. else signed_pair:=(a-256)*256+b;
  155. end;
  156. @#
  157. function get_three_bytes:integer; {returns the next three bytes, unsigned}
  158. var a,@!b,@!c:eight_bits;
  159. begin read(dvi_file,a); read(dvi_file,b); read(dvi_file,c);
  160. cur_loc:=cur_loc+3;
  161. get_three_bytes:=(a*256+b)*256+c;
  162. end;
  163. @#
  164. function signed_trio:integer; {returns the next three bytes, signed}
  165. var a,@!b,@!c:eight_bits;
  166. begin read(dvi_file,a); read(dvi_file,b); read(dvi_file,c);
  167. cur_loc:=cur_loc+3;
  168. if a<128 then signed_trio:=(a*256+b)*256+c
  169. else signed_trio:=((a-256)*256+b)*256+c;
  170. end;
  171. @#
  172. function signed_quad:integer; {returns the next four bytes, signed}
  173. var a,@!b,@!c,@!d:eight_bits;
  174. begin read(dvi_file,a); read(dvi_file,b); read(dvi_file,c); read(dvi_file,d);
  175. cur_loc:=cur_loc+4;
  176. if a<128 then signed_quad:=((a*256+b)*256+c)*256+d
  177. else signed_quad:=(((a-256)*256+b)*256+c)*256+d;
  178. end;
  179. @y
  180. @d read_dvi_file(#)==begin
  181. if dvi_count=block_size then begin
  182. get(dvi_file,@=error:=continue@>); dvi_count:=0;
  183. end;
  184. #:=dvi_file^[dvi_count];
  185. incr(dvi_count);
  186. end
  187.  
  188. @p function get_byte:integer; {returns the next byte, unsigned}
  189. var b:eight_bits;
  190. begin if eof(dvi_file) then get_byte:=0
  191. else  begin read_dvi_file(b); incr(cur_loc); get_byte:=b;
  192.   end;
  193. end;
  194. @#
  195. function signed_byte:integer; {returns the next byte, signed}
  196. var b:eight_bits;
  197. begin read_dvi_file(b); incr(cur_loc);
  198. if b<128 then signed_byte:=b @+ else signed_byte:=b-256;
  199. end;
  200. @#
  201. function get_two_bytes:integer; {returns the next two bytes, unsigned}
  202. var a,@!b:eight_bits;
  203. begin read_dvi_file(a); read_dvi_file(b);
  204. cur_loc:=cur_loc+2;
  205. get_two_bytes:=a*256+b;
  206. end;
  207. @#
  208. function signed_pair:integer; {returns the next two bytes, signed}
  209. var a,@!b:eight_bits;
  210. begin read_dvi_file(a); read_dvi_file(b);
  211. cur_loc:=cur_loc+2;
  212. if a<128 then signed_pair:=a*256+b
  213. else signed_pair:=(a-256)*256+b;
  214. end;
  215. @#
  216. function get_three_bytes:integer; {returns the next three bytes, unsigned}
  217. var a,@!b,@!c:eight_bits;
  218. begin read_dvi_file(a); read_dvi_file(b); read_dvi_file(c);
  219. cur_loc:=cur_loc+3;
  220. get_three_bytes:=(a*256+b)*256+c;
  221. end;
  222. @#
  223. function signed_trio:integer; {returns the next three bytes, signed}
  224. var a,@!b,@!c:eight_bits;
  225. begin read_dvi_file(a); read_dvi_file(b); read_dvi_file(c);
  226. cur_loc:=cur_loc+3;
  227. if a<128 then signed_trio:=(a*256+b)*256+c
  228. else signed_trio:=((a-256)*256+b)*256+c;
  229. end;
  230. @#
  231. function signed_quad:integer; {returns the next four bytes, signed}
  232. var a,@!b,@!c,@!d:eight_bits;
  233. begin read_dvi_file(a); read_dvi_file(b); read_dvi_file(c); read_dvi_file(d);
  234. cur_loc:=cur_loc+4;
  235. if a<128 then signed_quad:=((a*256+b)*256+c)*256+d
  236. else signed_quad:=(((a-256)*256+b)*256+c)*256+d;
  237. end;
  238. @z
  239.  
  240. @x [37]
  241. @ We need a function that will read in a word from the \.{TFM} file.  If
  242. the particular system
  243. @^system dependencies@>
  244. requires buffering, here is the place to do it.  It also sets a global flag
  245. |eof_tfm| when it reaches the end of the file.  If this flag is set on
  246. entrance to |load_tfm_file|, it is assumed that the file is bad.
  247.  
  248. @p function tfm_integer : integer ;
  249. var i:integer;
  250. begin read(tfm_file, i);
  251. eof_tfm:=eof(tfm_file);
  252. tfm_integer:=i;
  253. end;
  254.  
  255. @ There is nothing wrong with defining |eof_tfm| here.
  256.  
  257. @<Glob...@>=
  258. @!eof_tfm:boolean;  {true when end of \.{TFM} file is reached.}
  259. @y
  260. @ We need a function that will read in a word from the \.{TFM} file.  If
  261. the particular system
  262. @^system dependencies@>
  263. requires buffering, here is the place to do it.  It also sets a global flag
  264. |eof_tfm| when it reaches the end of the file.  If this flag is set on
  265. entrance to |load_tfm_file|, it is assumed that the file is bad.
  266.  
  267. Since |tfm_file| is blocked, we need a function to read an integer
  268. from it.
  269.  
  270. @d read_tfm_file(#)==begin
  271.    if tfm_count=block_size then begin
  272.       get(tfm_file); tfm_count:=0;
  273.       end;
  274.    #:=tfm_file^[tfm_count];
  275.    incr(tfm_count);
  276.    end
  277. @#
  278. @p function tfm_integer : integer;
  279. var i,@!result,@!temp:integer;
  280. begin
  281.    result := 0;
  282.    for i:=1 to 4 do begin@/
  283.        read_tfm_file(temp); result := result*two_8+temp;
  284.    end;
  285.    eof_tfm := eof(tfm_file);
  286.    tfm_integer := result ;
  287. end;
  288.  
  289. @ There is nothing wrong with defining |eof_tfm| here.
  290.  
  291. @<Glob...@>=
  292. @!eof_tfm:boolean;  {true when end of \.{TFM} file is reached.}
  293. @z
  294.  
  295.  
  296. @x
  297. and |term_out| for terminal output.
  298. @^system dependencies@>
  299.  
  300. @<Glob...@>=
  301. @!buffer:array[0..terminal_line_length] of ASCII_code;
  302. @!term_in:text_file; {the terminal, considered as an input file}
  303. @!term_out:text_file; {the terminal, considered as an output file}
  304. @y
  305. and |term_out| for terminal output.
  306. @^system dependencies@>
  307.  
  308. @d term_in==input {the terminal, considered as an input file}
  309. @d term_out==output {the terminal, considered as an output file}
  310.  
  311. @<Glob...@>=
  312. @!buffer:array[0..terminal_line_length] of ASCII_code;
  313. @!buf_length:integer;
  314. @z
  315.  
  316. @x
  317. @ Since the terminal is being used for both input and output, some systems
  318. need a special routine to make sure that the user can see a prompt message
  319. before waiting for input based on that message. (Otherwise the message
  320. may just be sitting in a hidden buffer somewhere, and the user will have
  321. no idea what the program is waiting for.) We shall call a system-dependent
  322. subroutine |update_terminal| in order to avoid this problem.
  323. @^system dependencies@>
  324.  
  325. @d update_terminal == break(term_out) {empty the terminal output buffer}
  326.  
  327. @ During the dialog, \vutex\ will treat the first blank space in a
  328. line as the end of that line. Therefore |input_ln| makes sure that there
  329. is always at least one blank space in |buffer|.
  330. @^system dependencies@>
  331.  
  332. @p procedure input_ln; {inputs a line from the terminal}
  333. var k:0..terminal_line_length;
  334. begin update_terminal; reset(term_in);
  335. if eoln(term_in) then read_ln(term_in);
  336. k:=0;
  337. while (k<terminal_line_length)and not eoln(term_in) do
  338.   begin buffer[k]:=xord[term_in^]; incr(k); get(term_in);
  339.   end;
  340. buffer[k]:=" ";
  341. end;
  342. @y
  343. @ Since the terminal is being used for both input and output, some systems
  344. need a special routine to make sure that the user can see a prompt message
  345. before waiting for input based on that message. (Otherwise the message
  346. may just be sitting in a hidden buffer somewhere, and the user will have
  347. no idea what the program is waiting for.) We shall call a system-dependent
  348. subroutine |update_terminal| in order to avoid this problem.
  349. @^system dependencies@>
  350.  
  351. @d update_terminal == do_nothing {empty the terminal output buffer}
  352.  
  353. @ During the dialog, \vutex\ will treat the first blank space in a
  354. line as the end of that line. Therefore |input_ln| makes sure that there
  355. is always at least one blank space in |buffer|.
  356. @^system dependencies@>
  357.  
  358. @p procedure input_ln; {inputs a line from the terminal}
  359. var k:0..terminal_line_length;
  360. begin update_terminal; reset(term_in) ;
  361. k:=0;
  362. if eoln(term_in) then write_ln
  363. else begin
  364.    while (k<terminal_line_length)and not eoln(term_in) do begin
  365.      buffer[k]:=xord[term_in^];
  366.      incr(k); get(term_in);
  367.      end;
  368.    end;
  369. buffer[k]:=" ";
  370. end;
  371. @z
  372.  
  373.  
  374. @x [52]
  375. @p procedure dialog;
  376. var k:integer; {loop variable}
  377. begin rewrite(term_out); {prepare the terminal for output}
  378. @<Determine the desired |start_count| values@>;
  379. @<Determine the desired |max_pages|@>;
  380. @<Determine the truncation |print_width|@>;
  381. @<Determine the compression mode@>;
  382. @<Print all the selected options@>;
  383. if compress and (print_width > (page_width * 3 div 4)) then
  384.       page_width := 4 * print_width div 3
  385. else if (not compress) and (print_width > page_width - hh_offset) then
  386.       page_width := print_width + hh_offset;
  387. if page_width > max_p_width then
  388.    begin
  389.       page_width := max_p_width;
  390.       print_width := page_width - hh_offset;
  391.    end;
  392. num_lines := total_rast div page_width;
  393. end;
  394. @y
  395.  
  396. @d batch == 0   { batch mode response}
  397. @d online == 1  { online mode response}
  398.  
  399. @p procedure dialog;
  400. var i, k:integer; {loop variable}
  401. interaction: integer; { to contain response from mode query}
  402.  
  403. begin rewrite(term_out); {prepare the terminal for output}
  404. if buf_length<=0 then begin
  405.    @<Determine the desired |start_count| values@>;
  406.    @<Determine the desired |max_pages|@>;
  407.    @<Determine the truncation |print_width|@>;
  408.    @<Determine the compression mode@>;
  409.    @<Print all the selected options@>;
  410. end else @<Determine the options from the command buffer@>;
  411. if compress and (print_width > (page_width * 3 div 4)) then
  412.       page_width := 4 * print_width div 3
  413. else if (not compress) and (print_width > page_width - hh_offset) then
  414.       page_width := print_width + hh_offset;
  415. if page_width > max_p_width then
  416.    begin
  417.       page_width := max_p_width;
  418.       print_width := page_width - hh_offset;
  419.    end;
  420. num_lines := total_rast div page_width;
  421. end;
  422.  
  423.  
  424. @ Here are  two new sections to support getting the options from the
  425. command line.
  426.  
  427. @<Determine the options...@>==
  428.  begin
  429.    buffer[buf_length+1] := "?" ; { end it with a question mark }
  430.    buf_ptr := 0 ;
  431.    repeat
  432.          case buffer[buf_ptr] of
  433.          " ",",","G","g" : ;
  434.          "S","s" : begin
  435.             @<Skip to parameter@> ; k := 0 ;
  436.             @<Parse the desired |start_vals|@> ;
  437.                end ;
  438.          "P","p" : begin
  439.             @<Skip to parameter@> ;
  440.             @<Parse the desired |max_pages|@> ;
  441.                end ;
  442.          "W","w" : begin
  443.             @<Skip to parameter@> ;
  444.             @<Parse the desired |print_width|@> ;
  445.                end ;
  446.          "T","t" : compress := false ;
  447.          "D","d" : out_mode := 1 ;
  448.          othercases
  449.             print_ln('Error on command line. Skipping: ',xchr[buffer[buf_ptr]]);
  450.             @.Error on command line...:@>
  451.          endcases ;
  452.          incr(buf_ptr);
  453.    until buf_ptr >= buf_length;
  454.    @<Print all the selected options@>;
  455. end
  456.  
  457. @ @<Skip to parameter@>==
  458. while (buf_ptr < buf_length) and (buffer[buf_ptr] <> " ") and
  459.  (buffer[buf_ptr] <> "=") and (buffer[buf_ptr] <> ",") do
  460.    incr(buf_ptr);
  461. if buffer[buf_ptr] = "=" then incr(buf_ptr);
  462. @z
  463.  
  464.  
  465. @x [68] set up directory names
  466. @d tfm_directory_name=='TeXfonts:'
  467. @d tfm_directory_name_length=9
  468. @y
  469. @d tfm_directory_name=='staff:[wolfe]'
  470. @d tfm_directory_name_length=13
  471. @z
  472.  
  473.  
  474. @x [122]
  475. @d font_list_file=='nonASCII.tex.fnt' {change this to correct name}
  476. @d list_len==16
  477. @y
  478. @d font_list_file=='nonASCIItex.dat'
  479. @d list_len==23
  480. @z
  481.  
  482. @x [207]
  483. This section should be replaced, if necessary, by changes to the program
  484. that are necessary to make \vutex\ work at a particular installation.
  485. Any additional routines should be inserted here.
  486. @^system dependencies@>
  487. @y
  488. Here are the remaining changes to the program
  489. that are necessary to make \.{DVItype} work on Vax/VMS.
  490.  
  491. @<Const...@>==
  492. @!block_size=512;
  493. @!two_8= @'400;
  494.  
  495. @ @<Types...@>==
  496. @!byte_block=packed array [0..block_size-1] of 0..255;
  497.  
  498. @ On Vax/VMS we need the following special definitions, types, variables
  499. and procedures to be able to get the file name from the command line,
  500. or to prompt for them.
  501.  
  502. @d VAX_direct==@=direct@>
  503. @d VAX_fixed==@=fixed@>
  504. @d VAX_volatile==@=volatile@>
  505. @d VAX_immed==@=%immed @>
  506. @d VAX_external==@=external@>
  507. @d VAX_stdescr==@=%stdescr @>
  508. @d VAX_lib_get_foreign==@= lib$get_foreign@>
  509. @d VAX_length==@=length @>
  510. @d VAX_fab_type==@= FAB$TYPE @>
  511. @d VAX_rab_type==@= RAB$TYPE @>
  512. @d VAX_xab_type==@= XAB$TYPE @>
  513. @d VAX_fab_xab==@= FAB$L_XAB @>
  514. @d VAX_xab_nxt==@= XAB$L_NXT @>
  515. @d VAX_xab_cod==@= XAB$B_COD @>
  516. @d VAX_xab_fhc==@= XAB$C_FHC @>
  517. @d VAX_xab_ebk==@= XAB$L_EBK @>
  518.  
  519. @ @<Types...@>=
  520. @!sixteen_bits= 0..65535;
  521.  
  522. @ @<Glob...@>==
  523. @!type_file: text;
  524. @!com_line:packed array[1..300] of char;
  525. @!cmd_len:sixteen_bits;
  526. @!cmd_i,cmd_e,cmd_o:integer;
  527. @!dvi_fname,@!bit_fname:varying [300] of char;
  528. @!got_file_name: boolean;
  529.  
  530. @ @<Preset init...@>=
  531. open(output,'SYS$OUTPUT',@=error:=continue@>); {FIX ME! JUNK FOR RUN-TIME BUG}
  532. cmd_i:=0;
  533. VAX_lib_get_foreign(com_line,,cmd_len,cmd_i);
  534. cmd_i:=1;
  535. while (cmd_i<=cmd_len) and (com_line[cmd_i]=' ') do incr(cmd_i);
  536.  
  537. cmd_o:=cmd_i;
  538. while (cmd_o<cmd_len) and (com_line[cmd_o]<>'\') do incr(cmd_o);
  539. if cmd_o<cmd_len then begin
  540.    for i:=1 to cmd_len-cmd_o do buffer[i-1] := ord(com_line[cmd_o+i]);
  541.    buf_length := cmd_len - cmd_o;
  542.    end
  543. else buf_length := 0;
  544. if cmd_o<cmd_len then cmd_len := cmd_o-1;
  545.  
  546. got_file_name:=(cmd_i<=cmd_o) and (cmd_len>0);
  547. if got_file_name then @<Parse names of files@>
  548. else @<Input names of files@>;
  549. open(dvi_file,dvi_fname,@=readonly@>,
  550.               @=user_action:=@>dvi_open,@=error:=continue@>);
  551. if status(dvi_file)<>0 then begin
  552.    write_ln('Cannot open dvi file!');
  553.    goto 9999;
  554.    end;
  555.  
  556. open(bit_file,bit_fname,@=new,32767@>,@=error:=continue@>);
  557. if status(bit_file)<>0 then begin
  558.    write_ln('Cannot open bit file or printer output');
  559.    goto 9999;
  560.    end;
  561.  
  562. @ If the name of the |dvi_file| appears in the command line, we parse it.
  563.  
  564. @<Parse names of files@>=
  565. begin cmd_e:=cmd_i+1;
  566. while (cmd_e<=cmd_len) and (com_line[cmd_e]<>' ') do incr(cmd_e);
  567. decr(cmd_e);
  568. dvi_fname:=substr(com_line,cmd_i,cmd_e-cmd_i+1)+'.DVI';
  569.  
  570. cmd_i:=cmd_e+1;
  571. while (cmd_i<=cmd_len) and (com_line[cmd_i]=' ') do incr(cmd_i);
  572. if cmd_i<cmd_o then begin
  573.    cmd_e:=cmd_i;
  574.    while (cmd_e<=cmd_len) and (com_line[cmd_e]<>' ') do incr(cmd_e);
  575.    decr(cmd_e);
  576.    bit_fname:=substr(com_line,cmd_i,cmd_e-cmd_i+1)+'.VUT';
  577.    end
  578. else bit_fname:='SYS$OUTPUT';
  579. end
  580.  
  581.  
  582. @ If the name of the |dvi_file| does not appear in the command line, we must
  583. get one from the user.
  584.  
  585. @<Input names of files@>=
  586. begin
  587. write('DVI file: ');
  588. if eof then goto 9999;
  589. read_ln(dvi_fname);
  590.  
  591. write('VUT file: ');
  592. if eof then goto 9999;
  593. read_ln(bit_fname);
  594. if bit_fname.VAX_length=0 then bit_fname:='SYS$OUTPUT';
  595. end
  596.  
  597. @ Here is the library procedure that gets the user's command line.
  598.  
  599. @<Procedures for ...@>=
  600. [VAX_external] function VAX_lib_get_foreign(
  601.   VAX_stdescr cmdlin:[VAX_volatile] packed array [$l1..$u1:integer] of char
  602.      := VAX_immed 0;
  603.   VAX_stdescr prompt:[VAX_volatile] packed array [$l2..$u2:integer] of char
  604.      := VAX_immed 0;
  605.   var len  : [VAX_volatile] sixteen_bits := VAX_immed 0;
  606.   var flag : [VAX_volatile] integer      := VAX_immed 0)
  607.      :integer; extern;
  608.  
  609. @ Here is how we intervene to find out the length of the |dvi_file|.
  610.  
  611. @<Procedures for ...@>=
  612. function dvi_open(var fab:VAX_fab_type; var rab:VAX_rab_type):integer;
  613. type XAB_ptr = ^VAX_xab_type;
  614. var user_status:integer;
  615.     xab,fhc:XAB_ptr;
  616. begin
  617. user_status:=@= $OPEN@>(fab);
  618. if odd(user_status) then @= $CONNECT@>(rab);
  619. xab:=fab.VAX_fab_xab::XAB_ptr;
  620. fhc:=nil;
  621. while (xab<>nil) and (fhc=nil) do
  622.    if xab^.VAX_xab_cod=VAX_xab_fhc then fhc:=xab
  623.    else xab:=xab^.VAX_xab_nxt::XAB_ptr;
  624. if fhc<>nil then dvi_blocks:=int(fhc^.VAX_xab_ebk)
  625. else dvi_blocks:=0;
  626.  
  627. dvi_open:=user_status;
  628. end;
  629.  
  630. @z
  631.  
  632.  
  633.